package com.splant.android.smart.SystemDefinedLevel.Services;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.widget.Toast;

import com.splant.android.smart.CommunicationLevel.UDPClient;
import com.splant.android.smart.GlobalConfig;
import com.splant.android.R;
import com.splant.android.smart.SystemDefinedLevel.Utils.System_DataType_Util;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

public class UdpService extends Service implements IUdpService {

    public final static int RECV_UDPDATAS = 100000;
    public final static int SEND_TIMEOUT = 100001;
    public final static int SEND_ERROR = 100002;
    protected final int RESEND_COUNT = 2;
    protected final int RESEND_INV = 2000;
    private UDPClient udpClient;
    private List<byte[]> sendBytesList = new ArrayList<>();
    protected Handler recvHandler;


    private Handler handler=new Handler()
    {
        @Override
        public void handleMessage(Message msg)
        {
            if (msg.what==SEND_ERROR)
            {
               // Toast.makeText(UdpService.this, getString(R.string.gaiaa_network_error_txt), Toast.LENGTH_SHORT).show();
            }
        }

    };
    public UdpService() {

    }
    public void setRecvHandler(Handler handler) {
        if (handler!=null)
        this.recvHandler = handler;
    }
    @Override
    public void onCreate() {

        try
        {
            if (commThread == null) {
                commThread = new CommThread();
                commThread.start();

                commTimerTask = new CommTimerTask();
                new Timer().schedule(commTimerTask, 50, RESEND_INV);
            }

        } catch (Exception e) {

        }
    }

    public void sendSingleOrder(byte[] orderBytes) {
        sendCount = 0;
        sendBytesList.clear();
        sendBytesList.add(orderBytes);
        sendDatas(sendBytesList.get(0));
    }

    public void sendOrderList(List<byte[]> orderList) {
        sendCount = 0;
        sendBytesList.clear();
        sendBytesList.addAll(orderList);
        sendDatas(sendBytesList.get(0));
    }

    private void sendDatas(byte[] datas) {
        try
        {
            SendDatasThread sendDatasThread = new SendDatasThread(datas);
            sendDatasThread.start();

        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void handleRecvMsg(byte[] bytes) {

        if (recvHandler != null) {
            recvHandler.obtainMessage(RECV_UDPDATAS, bytes).sendToTarget();
        }

    }

    private class SendDatasThread extends Thread {

        private byte[] sendDatas;

        public SendDatasThread(byte[] sendDatas) {
            this.sendDatas = sendDatas;
        }
        @Override
        public void run() {
            try
            {
                udpClient.send(GlobalConfig.UDP_SERVER_IP, GlobalConfig.UDP_SERVER_PORT, sendDatas);
                sendCount++;
                sendTime = System.currentTimeMillis();
                Log.i("CommData", System_DataType_Util.bytesToHexString(sendDatas, " "));
            }
            catch (Exception e)
            {
                if (sendCount == 0)
                {
                    if (recvHandler!=null)
                        recvHandler.sendEmptyMessage(SEND_ERROR);
                    else
                      handler.sendEmptyMessage(SEND_ERROR);
                }
                sendBytesList.clear();
            }
        }
    }

    private CommThread commThread;

    private class CommThread extends Thread {
        @Override
        public void run() {
            try
            {

                if (udpClient == null) {
                    udpClient = new UDPClient();
                    udpClient.setSoTimeout(0);
                }
                while (true)
                {
                    try
                    {
                        byte[] recvBytes = udpClient.receive();

                        Log.i("CommData", System_DataType_Util.bytesToHexString(recvBytes, " "));

                        handleRecvMsg(recvBytes);

                    }
                    catch (Exception e)
                    {

                    }
                }
            }
            catch (Exception e)
            {

            }
        }
    }

    private long sendTime;
    private int sendCount;
    private CommTimerTask commTimerTask;

    private class CommTimerTask extends TimerTask {

        public CommTimerTask() {

        }
        @Override
        public void run() {

            long now = System.currentTimeMillis();
            if (now - sendTime >= RESEND_INV)//通讯超时
            {
                if (sendBytesList.size() > 0 && sendCount <= RESEND_COUNT)
                    sendDatas(sendBytesList.get(0));
                else {
                    sendCount = 0;
                    if (recvHandler != null && sendBytesList.size() > 0)
                        recvHandler.sendEmptyMessage(SEND_TIMEOUT);

                    sendBytesList.clear();
                }
            }

        }
    }

    public void finishTask() {
        sendBytesList.clear();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return new UdpBinder();
    }

    public class UdpBinder extends Binder {

        public UdpService getService() {
            return UdpService.this;
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        commThread.interrupt();
        commTimerTask.cancel();
    }
}
